using System;
using UnityEngine;

/// <summary>
///     mono��̳еĵ���
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;
    private static readonly object _lock = new();

    private static bool _destroyed;

    public static T Instance
    {
        get
        {
            var _type = typeof(T);
            if (_destroyed) return null;
            lock (_lock)
            {
                if (_instance == null)
                {
                    _instance = (T)FindFirstObjectByType(_type);

                    //�ų������п��ܴ��ڵĶ��ʵ��
                    //if (FindFirstObjectByType(_type)) //�滻ԭ�ȵľɰ����
                    //{
                    //    //Debug.LogErrorFormat("[Singleton]���͡�{0}�����ڶ��ʵ��.", _type.Name);
                    //    return _instance;
                    //}
                    if (_instance == null)
                    {
                        var customAttributes = _type.GetCustomAttributes(typeof(AutoSingletonAttribute), true);
                        var autoAttribute = customAttributes.Length > 0
                            ? (AutoSingletonAttribute)customAttributes[0]
                            : null;
                        if (null == autoAttribute || !autoAttribute.autoCreate) return null;
                        GameObject go = null;
                        if (string.IsNullOrEmpty(autoAttribute.resPath))
                        {
                            go = new GameObject(_type.Name);
                            _instance = go.AddComponent<T>();
                        }
                        else
                        {
                            go = Resources.Load<GameObject>(autoAttribute.resPath);
                            if (null != go)
                                go = Instantiate(go);
                            else
                                return null;
                            _instance = go.GetComponent<T>();
                        }
                    }
                }

                return _instance;
            }
        }
    }

    protected virtual void Awake()
    {
        if (_instance != null && _instance.gameObject != gameObject)
        {
            //if (Application.isPlaying)
            //{
            //    GameObject.Destroy(gameObject);
            //}
            //else
            //{
            //    GameObject.DestroyImmediate(gameObject);
            //}
        }
        //_instance = GetComponent<T>();
        //if (!transform.parent) //Unity ֻ����������ڵ�� ��Ϸ�������ټ��ء�
        //{
        //    //DontDestroyOnLoad(gameObject);
        //}
        //OnInit();
    }

    /// <summary>
    ///     ������ֹͣʱ��Unity �������˳�����ٶ���
    ///     ������ gameObject ���������������٣����ų���������ٴα����õĿ����ԡ�
    ///     �ʶ��ڱ༭��ģʽ�£����㲥��ֹͣ�ˣ�Ҳ���ܻ�����һ�� gameObject ��������ڱ༭�������С�
    ///     ���ԣ��˷����мӰ��������ⲻ��Ҫ�ĵ�������
    /// </summary>
    public void OnDestroy()
    {
        if (_instance != null && _instance.gameObject == gameObject)
        {
            _instance = null;
            _destroyed = true;
        }
    }

    public static void DestroyInstance()
    {
        if (_instance != null) Destroy(_instance.gameObject);
        _destroyed = true;
        _instance = null;
    }

    /// <summary>
    ///     ��� _destroyed ��
    /// </summary>
    public static void ClearDestroy()
    {
        DestroyInstance();
        _destroyed = false;
    }

    /// <summary>Awake ��ʼ�����֮�� </summary>
    public virtual void OnInit()
    {
    }
}

[AttributeUsage(AttributeTargets.Class)]
public class AutoSingletonAttribute : Attribute
{
    public bool autoCreate; //�Ƿ��Զ���������
    public string resPath; //��ָ����Ԥ����·�����ɵ���

    public AutoSingletonAttribute(bool _autoCreate, string _resPath = "")
    {
        autoCreate = _autoCreate;
        resPath = _resPath;
    }
}